package com.financial.transactionhistory.service.impl;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.alibaba.fastjson2.JSON;
import com.financial.common.constant.CacheConstants;
import com.financial.common.utils.DateUtils;
import com.financial.common.utils.SecurityUtils;
import com.financial.transactionhistory.domain.FinancialTransaction;
import com.financial.transactionhistory.dto.FinancialBudgetAddDto;
import com.financial.transactionhistory.dto.FinancialBudgetListDto;
import com.financial.transactionhistory.vo.FinancialBudgetVo;
import com.financial.transactionhistory.vo.FinancialTransactionVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.financial.transactionhistory.mapper.FinancialBudgetMapper;
import com.financial.transactionhistory.domain.FinancialBudget;
import com.financial.transactionhistory.service.IFinancialBudgetService;

import com.financial.transactionhistory.mapper.FinancialBudgetMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 预算Service业务层处理
 *
 * @author chenda
 * @date 2025-06-16
 */
@Service
public class FinancialBudgetServiceImpl extends ServiceImpl<FinancialBudgetMapper, FinancialBudget> implements IFinancialBudgetService
{
    @Autowired
    private FinancialBudgetMapper financialBudgetMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 查询预算
     *
     * @param id 预算主键
     * @return 预算
     */
    @Override
    public FinancialBudgetVo selectFinancialBudgetById(Long id)
    {
        //先查询redis中的数据
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_BUDGET_LIST_KEY + userIdStr;
        List<String>  financialBudgetRedsiList = redisTemplate.opsForList().range(cacheKey, 0, -1);
        if (financialBudgetRedsiList.size()>0){
            FinancialBudgetVo financialBudgetVo = new FinancialBudgetVo();
            //遍历从redis中查询到的商品
            financialBudgetRedsiList.forEach(x->{
                //把查询到的商品转化成对象
                FinancialBudget financialBudget = JSON.parseObject(x, FinancialBudget.class);
                Long finBalanceId = financialBudget.getId();
                if (finBalanceId==id){
                    BeanUtils.copyProperties(financialBudget, financialBudgetVo);
                }
            });
            //返回对象
            return financialBudgetVo;
        }
        //redis中没有数据，根据交易id查询信息
        FinancialBudget one = this.lambdaQuery().eq(FinancialBudget::getId, id)
                .eq(FinancialBudget::getUserId, SecurityUtils.getUserId()).one();
        //复制
        FinancialBudgetVo vo = new FinancialBudgetVo();
        BeanUtils.copyProperties(one, vo);
        return vo;
    }

    /**
     * 查询预算列表
     *
     * @param
     * @return 预算
     */
    @Override
    public List<FinancialBudgetVo> selectFinancialBudgetList(FinancialBudgetListDto dto)
    {
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        Long userId = SecurityUtils.getUserId();
        //先查询redis
        String cacheKey = CacheConstants.FINANCIAL_BUDGET_LIST_KEY + userIdStr;
        List<String> budgetredisList = redisTemplate.opsForList().range(cacheKey, 0, -1);
        //查询到数据
        if (budgetredisList.size() > 0) {
            ArrayList<FinancialBudgetVo> financialBudgetVoArrayList = new ArrayList<>();
            //遍历到的数据转成json对象
            budgetredisList.forEach(x -> {
                FinancialBudgetVo financialBudgetVo = new FinancialBudgetVo();
                FinancialBudget financialBudget = JSON.parseObject(x, FinancialBudget.class);
                BeanUtils.copyProperties(financialBudget,financialBudgetVo);
                financialBudgetVoArrayList.add(financialBudgetVo);
            });
            if (CollectionUtils.isEmpty(financialBudgetVoArrayList) ) {
                return financialBudgetVoArrayList;
            }
            List<FinancialBudgetVo> financialBudgetVoList = financialBudgetVoArrayList.stream()
                    .filter(txn -> {
                        // 类型匹配
                        boolean budgetname = dto.getBudgetName() == null
                                || Objects.equals(txn.getBudgetName(), dto.getBudgetName());
                        // 分类匹配
                        boolean amount = dto.getAmount() == null
                                || Objects.equals(txn.getAmount(), dto.getAmount());
                        // 交易时间匹配
                        boolean startTime = dto.getStartTime() == null
                                || Objects.equals(txn.getStartTime(), dto.getStartTime());
                        boolean endTime = dto.getEndTime() == null
                                || Objects.equals(txn.getEndTime(), dto.getEndTime());
                        //所有条件都满足才保留
                        return budgetname && amount && startTime && endTime;
                    })
                    .collect(Collectors.toList());
            //返回数据
            return financialBudgetVoList;
        }
        //redis中查询不到，查询数据库
        List<FinancialBudget> financialBudgetList = this.lambdaQuery()
                .eq(dto.getBudgetName()!=null,FinancialBudget::getBudgetName, dto.getBudgetName())
                .eq(dto.getAmount()!=null,FinancialBudget::getAmount, dto.getAmount())
                .eq(dto.getStartTime()!=null ,FinancialBudget::getStartTime,dto.getStartTime())
                .eq(dto.getEndTime()!=null ,FinancialBudget::getEndTime,dto.getEndTime())
                .eq(FinancialBudget::getUserId, userId)
                .list();
        //封装结果
        List<FinancialBudgetVo> voList = new ArrayList<>();
        financialBudgetList.forEach(financialBudget -> {
            FinancialBudgetVo vo = new FinancialBudgetVo();
            BeanUtils.copyProperties(financialBudget,vo );
            voList.add(vo);
        });
        //查询所有数据
        List<FinancialBudget> financialBudgetList1 = this.lambdaQuery().eq(FinancialBudget::getUserId, userId).list();
        //保存到redis中
        if (financialBudgetList1 != null) {
            financialBudgetList1.forEach(x -> {
                x.setStartTime(LocalDate.parse(x.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
                x.setEndTime(LocalDate.parse(x.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
                //把数据转化成json字符串
                String string = JSON.toJSONString(x);
                redisTemplate.opsForList().leftPush(cacheKey, string);
            });
        }
        return  voList;
    }

    /**
     * 新增预算
     *
     * @param
     * @return 结果
     */
    @Override
    public int insertFinancialBudget(FinancialBudgetAddDto dto)
    {
        FinancialBudget financialBudget = new FinancialBudget();
        //复制
        BeanUtils.copyProperties(dto, financialBudget);
        financialBudget.setUserId(SecurityUtils.getUserId());//用户id
        //添加
        boolean save = this.save(financialBudget);
        if (!save) {
            return 0;
        }
        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_BUDGET_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;
    }

    /**
     * 修改预算
     *
     * @param
     * @return 结果
     */
    @Override
    public int updateFinancialBudget(FinancialBudgetAddDto dto)
    {
        FinancialBudget financialBudget = new FinancialBudget();
        //复制
        BeanUtils.copyProperties(dto, financialBudget);
        financialBudget.setUserId(SecurityUtils.getUserId());
        boolean b = this.updateById(financialBudget);
        if (!b){
            return 0;
        }
        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_BUDGET_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;

    }

    /**
     * 批量删除预算
     *
     * @param ids 需要删除的预算主键
     * @return 结果
     */
    @Override
    public int deleteFinancialBudgetByIds(Long[] ids)
    {
        boolean b = this.removeBatchByIds(Arrays.asList(ids));
        if (!b){
            return 0;
        }
        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_BUDGET_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;    }

    /**
     * 删除预算信息
     *
     * @param id 预算主键
     * @return 结果
     */
    @Override
    public int deleteFinancialBudgetById(Long id)
    {
                return removeById(id) ? 1 : 0;
    }
}